package main

import "fmt"

//结构体是值类型

type preson struct {
	name, gender string // 类型简写
}

// 函数定义
func f(x preson) {
	x.gender = "女"        // 修改的是副本的值，传参相当于copy
	fmt.Println(x.gender) // "女"
}
func f1(x *preson) { // 定义preson指针类型参数的函数
	(*x).gender = "女" // 通过*内存取值 修改为 女
	// x.gender = "女"    // 语法糖，自动根据指针找变量
}

func main() { // 入口
	// 1. 声明，初始化
	var p preson
	p.name = "致幻"
	p.gender = "男"
	fmt.Println(p.gender) //"男"
	f(p)                  // 函数调用输入 "女"
	fmt.Println(p.gender) // 还是"男"，因为函数内部修改的是副本的值，与P无关
	f1(&p)                // &获取p的内存地址
	fmt.Println(p.gender) // 女

	// 2.指针类型，还可以写成&preson
	var p2 = new(preson)
	p2.gender = "女"
	p2.name = "zhihuan" // 初始化指针类型的结构体
	//类型是*main.preson  p2的值是&{7a68696875616e e5a5b3}
	// p2的内存地址是 0xc0000ce020
	fmt.Printf("%T %x %p\n", p2, p2, &p2)

	// 3.声明并初始化,key-value初始化
	var p3 = preson{
		name:   "zhihuan",
		gender: "nan",
	}
	fmt.Printf("%#v", p3)

	// 4.值列表初始化，注意：值列表顺序要和定义的字段的顺序一样
	p4 := preson{
		"zhihuan",
		"nan",
	}
	fmt.Printf("%#v", p4)
}
